package com.ymh.git.thread.juc.goods;

import com.ymh.git.thread.juc.SleepTools;

import java.util.Random;
import java.util.concurrent.CountDownLatch;

/**
 * Created by aivin on 2018/11/6.
 * <p>
 * 对商品进行业务的应用
 */
public class BusiApp {

    static final int readWriteRatio = 10;//读写线程的比例
    static final int minThreadCount = 3;//最少线程数
    static CountDownLatch latch = new CountDownLatch(1);


    //读操作
    private static class GetThread implements Runnable {
        private GoodsService goodsService;

        public GetThread(GoodsService goodsService) {
            this.goodsService = goodsService;
        }

        @Override
        public void run() {
            try {
                latch.await(); //让读写线程同时运行
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            long start = System.currentTimeMillis();
            for (int i = 0; i < 100; i++) { //操作100次
                goodsService.getNum();
            }
            System.out.println(Thread.currentThread().getName() + "读取商品数据耗时：" + (System.currentTimeMillis() - start) + "ms");
        }
    }


    //写操作
    private static class SetThread implements Runnable {

        private GoodsService goodsService;

        public SetThread(GoodsService goodsService) {
            this.goodsService = goodsService;
        }

        @Override
        public void run() {
            try {
                latch.await();//让读写线程同时运行
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            long start = System.currentTimeMillis();
            Random random = new Random();
            for (int i = 0; i < 10; i++) {
                SleepTools.ms(50);
                goodsService.setNum(random.nextInt(10));
            }
            System.out.println(Thread.currentThread().getName() + "写入商品数据耗时：" + (System.currentTimeMillis() - start) + "ms");
        }

    }


    public static void main(String[] args) {
        GoodsInfo goodsInfo = new GoodsInfo("Cup", 100000, 10000);
//        GoodsService goodsService = new UseSync(goodsInfo);//使用内置锁方式
        GoodsService goodsService = new UseRwLock(goodsInfo);//使用读写锁方式
        for (int i = 0; i < minThreadCount; i++) {
            Thread setT = new Thread(new SetThread(goodsService));
            for (int j = 0; j < readWriteRatio; j++) {
                Thread getT = new Thread(new GetThread(goodsService));
                getT.start();
            }
            setT.start();
        }
        latch.countDown();
    }
}
